using System.Collections.Generic;
using Baula.Testing.Common;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Baula.TextGen.ActiveTemplating.Tests
{
    [TestClass]
    public class ExecutorTests
    {
        private Mock<IFormsContext> _formsContext;
        private Executor _executor;
        private Context _context;
        private Mock<ExecutionListener> _listener;

        [TestInitialize]
        public void TestInitialize()
        {
            _listener = new Mock<ExecutionListener>();
            _formsContext = new Mock<IFormsContext>();
            _context = new Context(null, _formsContext.Object, null);
            _executor = new Executor(_context);
            _executor.Listener = _listener.Object;
        }

        [TestMethod]
        public void CanInvokeListener()
        {
            _executor.Execute("Listener.Invoke()");
            _listener.Verify(l => l.Invoke(), Times.Once());
        }

        [TestMethod]
        public void CanInvokeFormsContext()
        {
            _executor.Execute(@"Dim NumberOfForms = Forms.Count");
            _formsContext.Verify(f => f.Count, Times.Once());
        }

        [TestMethod]
        public void CanLoopOverForms()
        {
            var forms = new List<IFormInfo>();
            forms.Add(new FormInfo("Form1"));
            forms.Add(new FormInfo("Form2"));
            _formsContext.Setup(fc => fc.GetEnumerator()).Returns(forms.GetEnumerator());
            _executor.Execute(@"
For Each Form In Forms
    Listener.Invoke()
Next");
            _listener.Verify(l => l.Invoke(), Times.Exactly(2));
        }

        [TestMethod]
        public void CanUseLambdaExpression()
        {
            _executor.Execute("Dim NeededForms = Forms.Where(Function(Form) Form.Name.Contains(\"2\"))");
            // Assert.Pass()
        }

        [TestMethod]
        public void CanReturnIntegerDebugOutput()
        {
            _executor.Execute(@"Context.IntegerDebugOutput = 123");
            Assert.AreEqual(123, _context.IntegerDebugOutput);
        }

        [TestMethod]
        public void CanBuildOutput()
        {
            _executor.Execute("AppendLine(\"Hello from VB!\")");
            _executor.Output.AssertEqualsIgnoringTrailingNewLine("Hello from VB!");
        }

        [TestMethod]
        public void CanAccessOutputThroughProperty()
        {
            _executor.Execute("AppendLine(\"Hello from VB!\")");
            _executor.Output.AssertEqualsIgnoringTrailingNewLine("Hello from VB!");
        }

        [TestMethod]
        public void CanAppendMultipleLines()
        {
            _executor.Execute(@"AppendLine(""Hello from line 1"")
AppendLine(""Hello from line 2"")");
            _executor.Output.AssertEqualsIgnoringTrailingNewLine("Hello from line 1\r\nHello from line 2");
        }
    }
}